package com.itstyle.seckill.topic.jichu;

/**
 * @Auther: liuwenxiang
 * @Date: 2020/3/12 00:22
 * @Description:
 * 原理：
 * 在ThreadLocal类中有一个Map，用于存储每一个线程的变量副本，
 * Map===key:"线程对象"，value:对应线程的"变量副本"。
 */
public class ThreadlocalTest {

    //①通过匿名内部类覆盖ThreadLocal的initialValue()方法，指定初始值
    private static ThreadLocal<Integer> seqNum =new ThreadLocal<Integer>(){
        @Override
        public Integer initialValue() {
            return 0;
        }
    };

    public int getNext(){
        seqNum.set(seqNum.get()+1);
        return seqNum.get();
    }


    public static void main(String[] args) {
        ThreadlocalTest threadlocalTest=new ThreadlocalTest();
        // ③ 3个线程共享threadlocalTest，各自产生序列号
        TestClient testClient1=new TestClient(threadlocalTest);
        TestClient testClient2=new TestClient(threadlocalTest);
        TestClient testClient3=new TestClient(threadlocalTest);
        testClient1.start();
        testClient2.start();
        testClient3.start();
        /**
         * 我们发现每个线程所产生的序号虽然都共享同一个TestNum实例，但它们并没有发生相互干扰的情况，
         * 而是各自产生独立的序列号，这是因为我们通过ThreadLocal为每一个线程提供了单独的副本
         */
    }

    public static class TestClient extends  Thread{

        private ThreadlocalTest threadlocalTest;

        private TestClient(ThreadlocalTest threadlocalTest){
            this.threadlocalTest=threadlocalTest;
        }

        @Override
        public void run(){
            for(int i=0;i<3;i++){
                // ④每个线程打出3个序列值
                System.out.println("thread[" + Thread.currentThread().getName() + "] --> sn["  +threadlocalTest.getNext()+ "]");
            }

        }
    }



}
